home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
422_02
/
cutil
/
ppc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-20
|
12KB
|
569 lines
/*
* PPC.C - Pretty Printer for C
* Created from CB on SIMTEL20 by Richard Conn
*
* Compile command: cc ppc -fop
*/
#include <stdio.h>
#define MAXBRAC 20 /* maximum number of open braces allowed */
#define IFLEVEL 20 /* maximum number of nested IFs allowed */
int slevel[IFLEVEL];
int spflg[MAXBRAC][IFLEVEL];
int sind [MAXBRAC][IFLEVEL];
int siflev[IFLEVEL];
int sifflg[IFLEVEL];
int clevel = 0; /* Number of open braces */
int iflev = 0; /* Number of active IFs */
int ifflg = -1; /* Indicates if we have an active IF */
int level = 0;
int ind[IFLEVEL]; /* Indentation amount for a particular IF */
int pflg[IFLEVEL]; /* Number of chars to indent for a particular IF */
int eflg = 0; /* We are in an ELSE? */
int paren = 0; /* Number of open parentheses */
int tabcount = 4; /* Number of characters to indent */
char tabchar = ' '; /* character to use for intenting */
char lchar;
char pchar;
int aflg = 0;
int stabs[MAXBRAC][IFLEVEL];
int qflg = 0;
/* The following are reserved words used for special processing */
char *wstr[] = {
"typedef",
"struct",
"union",
"int",
"char",
"unsigned",
"long",
"auto",
NULL
};
char *wrsvwds[] = {
"int",
"char",
"unsigned",
"long",
"auto",
NULL
};
char *wif[] = {
"if",
NULL
};
char *welse[] = {
"else",
NULL
};
char *wfor[] = {
"for",
NULL
};
char *wds[] = {
"case",
"default",
NULL
};
/* J is the index for the next character in the STRING buffer
STRING is the buffer in which the output line is built */
int j = 0;
char string[400];
char cc;
int sflg = 1;
int bflg = 0;
int peek = -1;
int tabs = 0;
int lastchar = ' ';
int cin;
/* Input and output buffers */
FILE *inpbuf;
FILE *outbuf;
main(argc, argv)
int argc;
char *argv[];
{
char bakfil[100]; /* name of current backup file */
int filno; /* number of current file */
int cont; /* local continuation flag */
int ct; /* count of local open parens */
int eflg; /* indicates we are in an ELSE */
int i;
if (argc == 1) {
printf ("Pretty Printer for C, Beta Test Version 1.0\n\n");
printf ("Syntax: ppc [-s#] [-T#] filename.ext [filename.ext ...]\n");
printf ("Options:\n");
printf (" -i[#] Indent # SPACES for each level (default = 4)\n");
printf (" -t[#] Indent # TABS for each level (default = 1)\n");
exit (0);
}
/* Zero indentation indicator and indent character count buffers */
for (i=0; i<IFLEVEL; ++i) {
ind[i] = 0;
pflg[i] = 0;
}
/* Main Loop */
for (filno=1; filno < argc; ++filno) {
/* Process next file (if not an option) */
if (*argv[filno] != '-') {
mkext (bakfil, argv[filno], "bak");
delete (bakfil);
rename (argv[filno], bakfil);
if ((inpbuf = fopen (bakfil, "r")) == NULL) {
fprintf(stderr,"Unable to read: %s\n", bakfil);
exit (1);
}
if ((outbuf = fopen (argv[filno], "w")) == NULL) {
fprintf(stderr,"Unable to write: %s\n", argv[filno]);
exit (1);
}
fprintf (stderr, "Pretty Printing %s\n", argv[filno]);
while ( (cin = getchr()) != EOF) {
switch(cin) {
case ' ':
case '\t':
if (lookup(welse) == 1) {
gotelse ();
if (sflg == 0 || j > 0) string[j++] =cin;
putz ();
sflg = 0;
break;
}
if (sflg == 0 || j > 0) string[j++] =cin;
break;
case '\n':
if ((eflg = lookup(welse)) == 1) gotelse();
putz();
fprintf (outbuf,"\n");
sflg = 1;
if (eflg == 1) {
++pflg[level];
++tabs;
}
else
if (pchar == lchar)
aflg = 1;
break;
case '{':
if (lookup(welse) == 1) gotelse();
siflev[clevel]= iflev;
sifflg[clevel]= ifflg;
iflev = ifflg = 0;
++clevel;
if (sflg == 1 && pflg[level] != 0) {
pflg[level]--;
tabs--;
}
string[j++] =cin;
putz ();
getnl ();
putz ();
fprintf (outbuf,"\n");
++tabs;
sflg = 1;
if (pflg[level] > 0) {
ind[level] = 1;
++level;
slevel[level] = clevel;
}
break;
case '}':
clevel--;
if ((iflev = siflev[clevel]-1) < 0) iflev = 0;
ifflg = sifflg[clevel];
putz ();
tabs--;
ptabs ();
if ((peek = getchr()) == ';') {
fprintf (outbuf, "%c;", cin);
peek = -1;
}
else fprintf (outbuf,"%c", cin);
getnl ();
putz ();
fprintf (outbuf,"\n");
sflg = 1;
if (clevel < slevel[level]) if (level > 0) level--;
if (ind[level] != 0) {
tabs -= pflg[level];
pflg[level] =0;
ind[level] = 0;
}
break;
case '"':
case '\'':
string[j++] =cin;
while ((cc = getc(inpbuf)) !=cin) {
string[j++] =cc;
if (cc == '\\') string[j++] = getc(inpbuf);
if (cc == '\n') {
putz();
sflg = 1;
}
}
string[j++] =cc;
if (getnl() ==1) {
lchar = cc;
peek = '\n';
}
break;
case ';':
string[j++] =cin;
putz ();
if (pflg[level] > 0 && ind[level] == 0) {
tabs -= pflg[level];
pflg[level] = 0;
}
getnl ();
putz ();
fprintf (outbuf,"\n");
sflg = 1;
if (iflev > 0)
if (ifflg == 1) {
iflev--;
ifflg = 0;
}
else iflev = 0;
break;
case '\\':
string[j++] =cin;
string[j++] =getchr();
break;
case '?':
qflg = 1;
string[j++] =cin;
break;
case ':':
string[j++] =cin;
if (qflg == 1) {
qflg = 0;
break;
}
if (lookup(wrsvwds) == 1) break;
if (lookup(wds)== 0) {
sflg = 0;
putz ();
}
else {
tabs--;
putz ();
++tabs;
}
if ((peek = getchr()) == ';') {
fprintf (outbuf, ";");
peek = -1;
}
getnl ();
putz ();
fprintf (outbuf,"\n");
sflg = 1;
break;
case '/':
string[j++] =cin;
if ((peek = getchr()) != '*') break;
string[j++] = peek;
peek = -1;
comment ();
break;
case ')':
paren--;
string[j++] = cin;
putz ();
if (getnl() == 1) {
peek = '\n';
if (paren != 0) aflg = 1;
else if (tabs > 0) {
++pflg[level];
++tabs;
ind[level] = 0;
}
}
break;
case '#':
string[j++] =cin;
while ((cc = getc(inpbuf)) != '\n') string[j++] = cc;
string[j++] =cc;
sflg = 0;
putz ();
sflg = 1;
break;
case '(':
string[j++] =cin;
++paren;
if (lookup(wfor) == 1) {
while ((cin = xgets()) != ';');
ct = 0;
cont = 1;
while (cont) {
while ((cin = xgets()) != ')') {
if (cin== '(') ++ct;
}
if(ct != 0) {
ct--;
}
else cont = 0;
}
paren--;
putz ();
if (getnl() ==1) {
peek = '\n';
++pflg[level];
++tabs;
ind[level] = 0;
}
break;
}
if (lookup(wif)== 1) {
putz ();
stabs[clevel][iflev] = tabs;
spflg[clevel][iflev] = pflg[level];
sind[clevel][iflev] = ind[level];
++iflev;
ifflg = 1;
}
break;
default:
string[j++] = cin;
if (cin != ',') lchar = cin;
break;
}
}
fclose (inpbuf);
fclose (outbuf);
}
/* Process an option */
else {
option (&argv[filno][1]);
}
}
}
/* Process an option on the command line */
option (item)
char *item;
{
switch (*item++) {
case 't' :
case 'T' :
tabchar = '\t';
tabcount = *item ? atoi (item) : 1;
break;
case 's' :
case 'S' :
tabchar = ' ';
tabcount = *item ? atoi (item) : 4;
break;
default :
fprintf (stderr, "Invalid option in command line: %s\n", item);
break;
}
}
/* Output leading indentation characters on the line */
ptabs()
{
int i, k;
for (i = 0; i < tabs; ++i) {
for (k = 0; k<tabcount; ++k)
putc(tabchar, outbuf);
}
}
/* Return the next no